package com.smzd.framework.workspace;

import java.security.Principal;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.smzd.framework.annotation.Access;
import com.smzd.framework.oauth2.business.ClientAppService;
import com.smzd.framework.oauth2.domain.ClientApp;
import com.smzd.framework.system.business.MenuService;
import com.smzd.framework.system.business.UserBindService;
import com.smzd.framework.system.business.UserService;
import com.smzd.framework.system.domain.Meeting;
import com.smzd.framework.system.domain.User;
import com.smzd.framework.system.domain.UserBind;
import com.smzd.framework.utils.MeetingSessionHolder;
import com.smzd.framework.utils.Privilege;
import com.smzd.utils.SessionHolder;

@Controller
public class FrameworkController implements InitializingBean {
    @Autowired
    private UserService userService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private UserBindService userBindService;
    @Autowired(required = false)
    private ClientAppService clientAppService;

    @Autowired(required = false)
    @Qualifier("frameworkViewConfiger")
    IFrameworkViewConfigure viewConfiger;

    @RequestMapping("/index.htm")
    public String toIndex(Map<String, Object> model, Principal principal) {
        model.put("principal", principal);
        return viewConfiger.getIndexView(model);
    }

    @RequestMapping("/workspace")
    @Access
    public String toWorkSpace(Map<String, Object> model) {
        User user = MeetingSessionHolder.getLoginUser();
        model.put("user", user);
        Meeting meeting = MeetingSessionHolder.getMeeting();
        model.put("meeting", meeting);
        return viewConfiger.getWorkspaceView(model);
    }

    @RequestMapping("/workspace/auth_failed")
    public String toAuthFailedPage(Map<String, Object> model, HttpServletRequest request) {
        Exception exception = SessionHolder.getObject("SPRING_SECURITY_LAST_EXCEPTION");
        String redirectUrl;
        SavedRequest req = SessionHolder.getObject("SPRING_SECURITY_SAVED_REQUEST");
        if (req == null) {
            String base = request.getContextPath();
            if (base == null || base.length() == 1) {
                base = "";
            }
            redirectUrl = base;
        } else {
            redirectUrl = req.getRedirectUrl();
        }
        model.put("redirect_url", redirectUrl);
        if ("验证码不正确".equals(exception.getMessage())) {
            model.put("msg", "验证码不正确");
        } else {
            model.put("msg", "用户名或密码错误");
        }
        return viewConfiger.getAuthFailedView(model);
    }

    @RequestMapping("/workspace/access_denied")
    public String toAccessDeniedPage(Map<String, Object> model) {

        return viewConfiger.getAccessDeniedView(model);
    }

    @RequestMapping("/workspace/login")
    public String toLoginPage(Map<String, Object> model, HttpServletRequest req) {
        DefaultSavedRequest request = SessionHolder.getObject("SPRING_SECURITY_SAVED_REQUEST");
        System.out.println("展示登录，为了访问：" + request);
        if (request != null) {
            model.put("savedRequest", request.getParameterMap());
            String requestUri = request.getRequestURI();
            if (requestUri != null && requestUri.endsWith("/oauth/authorize")) {// 由于要OAuth2而要求的登录
                // http://localhost:8080/UserCenter/oauth/authorize?client_id=35c813f5-dee1-467f-9b85-8d263a0b06f1&amp;redirect_uri=http://localhost:8080/xin2core/sso/xtwl_getticket?_type=1&amp;response_type=code&amp;scope=read+write&amp;state=xxx
                String[] clientIds = request.getParameterValues("client_id");
                if (clientIds != null && clientIds.length == 1) {
                    String clientId = clientIds[0];
                    ClientApp app = clientAppService.getClientAppByClientId(clientId);
                    model.put("clientApp", app);
                    return viewConfiger.getOAuthLoginView(model);
                }
            }
        }
        @SuppressWarnings("rawtypes")
        Map loginRequest = req.getParameterMap();
        model.put("loginRequest", loginRequest);
        return viewConfiger.getLoginView(model);
    }

    @Access
    @RequestMapping(value = "/workspace/nomeeting", method = RequestMethod.GET)
    public String toNoMeeting(Map<String, Object> model) {
        return viewConfiger.getNoMeetingView(model);
    }

    @Access
    @RequestMapping(value = "/workspace/meetings", method = RequestMethod.GET)
    public String toSelectMeetings(Map<String, Object> model) {
        User user = MeetingSessionHolder.getLoginUser();
        if (user.getType() == User.USER_TYPE_MEETING_MANAGER) {
            return "redirect:/workspace";
        }
        model.put("user", user);
        List<Meeting> meetings = MeetingSessionHolder.getMeetings();
        model.put("meetings", meetings);
        return viewConfiger.getSelectMeetingsView(model);
    }

    @Access
    @RequestMapping(value = "/workspace/meetings", method = RequestMethod.POST)
    public String doMeetingSelect(int id) throws Exception {
        User user = MeetingSessionHolder.getLoginUser();
        if (user.getType() == User.USER_TYPE_MEETING_MANAGER) {
            throw new Exception("身份与行为不符！");
        }
        List<Meeting> meetings = MeetingSessionHolder.getMeetings();
        for (Meeting meeting : meetings) {
            if (meeting.getId() - id == 0) {
                // 设置会务
                MeetingSessionHolder.setMeeting(meeting);
                // 设置权限
                Privilege privilege = userService.getPrivilegeForOwner(meeting);
                MeetingSessionHolder.setPrivilege(privilege);
                return "redirect:/workspace";
            }
        }
        throw new Exception("要选择的会务已经不存在了？");
    }

    @Access
    @RequestMapping(value = "/workspace/meetings/change", method = RequestMethod.GET)
    public String toChangeMeetings() {
        User user = MeetingSessionHolder.getLoginUser();
        if (user.getType() == User.USER_TYPE_MEETING_MANAGER) {
            return "redirect:/workspace";
        }
        List<Meeting> meetings = MeetingSessionHolder.getMeetings();
        if (meetings == null || meetings.size() < 2) {
            return "redirect:/workspace";
        }
        return "redirect:/workspace/meetings";
    }

    @RequestMapping(value = "/workspace/menus")
    // , method=RequestMethod.POST)
    @ResponseBody
    public String getMenus() {
        User user = MeetingSessionHolder.getLoginUser();
        int userType = user.getType();
        if (userType == User.USER_TYPE_MEETING_MANAGER) {
            return menuService.getMenuJsonByUserId(user.getId());
        } else if (userType == User.USER_TYPE_MEETING_OWNER) {
            Meeting meeting = MeetingSessionHolder.getMeeting();
            return menuService.getMenuJsonByMeetingId(meeting.getId());
        }
        return null;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (viewConfiger == null) {
            viewConfiger = new FrameworkViewConfigure();
        }
    }

    @RequestMapping("/workspace/binduser")
    public String bindUser(Map<String, Object> model) {
        User loginUser = MeetingSessionHolder.getLoginUser();
        if (loginUser != null) {
            User remote = SessionHolder.getObject("_remote_user_");
            if (remote != null) {// 远程用户已登录，绑定远程用户和本地用户
                SessionHolder.setObject("_remote_user_", null);
                UserBind userBind = new UserBind();
                userBind.setOwner(loginUser);
                userBind.setName(remote.getName());
                userBind.setOpenid(String.valueOf(remote.getId()));
                userBind.setType(UserBind.AUTH_TYPE_XTWL_OAUTH);
                userBindService.insert(userBind);
            } else {// 远程用户未登录，转到登录页面，这时可以选择要绑定的远程用户登录方式。
                DefaultSavedRequest request = SessionHolder.getObject("_SPRING_SECURITY_SAVED_REQUEST_");
                if (request != null) {
                    SessionHolder.setObject("_SPRING_SECURITY_SAVED_REQUEST_", request);
                }
                return "redirect:" + viewConfiger.getBindUserLoginPage();
            }
        } else {
            // 本地用户未登录这是不可能的。因此这个地方抛出一个异常来就行了。
            // 1. 创建本地用户
            // 2. 创建绑定
            User remote = SessionHolder.getObject("_remote_user_");
            if (remote != null) {
                // int type = SessionHolder.getObject("_remote_user_type_");

            } else {
                throw new RuntimeException("绑定用户时未找到本地用户未登录！");
            }
        }

        // 绑定成功！
        DefaultSavedRequest request = SessionHolder.getObject("_SPRING_SECURITY_SAVED_REQUEST_");
        if (request != null) {
            SessionHolder.setObject("_SPRING_SECURITY_SAVED_REQUEST_", null);
            String redirectUrl = request.getRedirectUrl();
            return "redirect:" + redirectUrl;
        }

        return "redirect:" + viewConfiger.getBindUserSuccessView();
    }

    @RequestMapping("/workspace/cancelbinduser")
    public String cancelBindUser() {
        System.out.println("cancelbinduser!!!");
        SessionHolder.setObject("_remote_user_", null);
        return "redirect:/workspace";
    }
    
    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String toRegistryPage(Map<String, Object> model) {
        return viewConfiger.getRegisterPage(model);
    }
    @RequestMapping(value = "/success", method = RequestMethod.GET)
    public String toSuccessPage(Map<String, Object> model) {
        return viewConfiger.getSuccessPage(model);
    }
}
